Sync with NautilusPlacesSidebar
authorFederico Mena Quintero <federico@gnome.org>
Fri, 7 Sep 2012 15:04:42 +0000 (10:04 -0500)
committerFederico Mena Quintero <federico@gnome.org>
Fri, 7 Sep 2012 16:11:20 +0000 (11:11 -0500)
This syncs the code up to commit 4b6abf644b from Nautilus.
This only refers to nautilus-places-sidebar.[ch].

Signed-off-by: Federico Mena Quintero <federico@gnome.org>
gtk/gtkplacessidebar.c

index 0eb030a1899911fd909a6b54dac6315a8568ca09..0ac7d013bac56fa9f45e51cf1452066089c40989 100644 (file)
  *
  */
 
+/* TODO:
+ *
+ * * Fix instances of "#if DO_NOT_COMPILE"
+ *
+ * * Fix instances of "#if 0"
+ *
+ * * Fix FIXMEs
+ *
+ * * Nautilus needs to use gtk_places_sidebar_set_uri() instead of built-in
+ *   notification from the NautilusWindowSlot.
+ */
+
 #include "config.h"
 
 #include <gio/gio.h>
@@ -61,7 +73,6 @@ struct _GtkPlacesSidebar {
        GtkCellRenderer    *eject_icon_cell_renderer;
        char               *uri;
        GtkListStore       *store;
-       GtkTreeModel       *filter_model;
        GtkBookmarksManager *bookmarks_manager;
        GVolumeMonitor *volume_monitor;
 
@@ -87,12 +98,18 @@ struct _GtkPlacesSidebar {
        GtkWidget *popup_menu_empty_trash_item;
        GtkWidget *popup_menu_start_item;
        GtkWidget *popup_menu_stop_item;
+       GtkWidget *popup_menu_properties_separator_item;
+       GtkWidget *popup_menu_properties_item;
 
        /* volume mounting - delayed open process */
        gboolean mounting;
+#if 0
+       NautilusWindowSlot *go_to_after_mount_slot;
+#endif
        GtkPlacesOpenMode go_to_after_mount_open_mode;
 
-       GtkTreePath *eject_highlight_path;
+       GDBusProxy *hostnamed_proxy;
+       char *hostname;
 
        guint multiple_tabs_supported : 1;
        guint multiple_windows_supported : 1;
@@ -119,13 +136,13 @@ enum {
        PLACES_SIDEBAR_COLUMN_VOLUME,
        PLACES_SIDEBAR_COLUMN_MOUNT,
        PLACES_SIDEBAR_COLUMN_NAME,
-       PLACES_SIDEBAR_COLUMN_ICON,
+       PLACES_SIDEBAR_COLUMN_GICON,
        PLACES_SIDEBAR_COLUMN_INDEX,
        PLACES_SIDEBAR_COLUMN_EJECT,
        PLACES_SIDEBAR_COLUMN_NO_EJECT,
        PLACES_SIDEBAR_COLUMN_BOOKMARK,
        PLACES_SIDEBAR_COLUMN_TOOLTIP,
-       PLACES_SIDEBAR_COLUMN_EJECT_ICON,
+       PLACES_SIDEBAR_COLUMN_EJECT_GICON,
        PLACES_SIDEBAR_COLUMN_SECTION_TYPE,
        PLACES_SIDEBAR_COLUMN_HEADING_TEXT,
 
@@ -134,6 +151,7 @@ enum {
 
 typedef enum {
        PLACES_BUILT_IN,
+       PLACES_XDG_DIR,
        PLACES_MOUNTED_VOLUME,
        PLACES_BOOKMARK,
        PLACES_HEADING,
@@ -192,8 +210,8 @@ static void bookmarks_check_popup_sensitivity          (GtkPlacesSidebar *sideba
 
 /* Identifiers for target types */
 enum {
-  GTK_TREE_MODEL_ROW,
-  TEXT_URI_LIST
+       GTK_TREE_MODEL_ROW,
+       TEXT_URI_LIST
 };
 
 /* Target types for dragging from the shortcuts list */
@@ -209,30 +227,28 @@ static const GtkTargetEntry dnd_drop_targets [] = {
 
 /* Drag and drop interface declarations */
 typedef struct {
-  GtkTreeModelFilter parent;
+       GtkListStore parent;
 
-  GtkPlacesSidebar *sidebar;
-} ShortcutsModelFilter;
+       GtkPlacesSidebar *sidebar;
+} ShortcutsModel;
 
 typedef struct {
-  GtkTreeModelFilterClass parent_class;
-} ShortcutsModelFilterClass;
+       GtkListStoreClass parent_class;
+} ShortcutsModelClass;
 
-#define SHORTCUTS_MODEL_FILTER_TYPE (shortcuts_model_filter_get_type ())
-#define SHORTCUTS_MODEL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHORTCUTS_MODEL_FILTER_TYPE, ShortcutsModelFilter))
+#define SHORTCUTS_MODEL_TYPE (shortcuts_model_get_type ())
+#define SHORTCUTS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHORTCUTS_MODEL_TYPE, ShortcutsModel))
 
-static GType shortcuts_model_filter_get_type (void);
-static void shortcuts_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface);
+static GType shortcuts_model_get_type (void);
+static void shortcuts_model_drag_source_iface_init (GtkTreeDragSourceIface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (ShortcutsModelFilter,
-                        shortcuts_model_filter,
-                        GTK_TYPE_TREE_MODEL_FILTER,
+G_DEFINE_TYPE_WITH_CODE (ShortcutsModel,
+                        shortcuts_model,
+                        GTK_TYPE_LIST_STORE,
                         G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
-                                               shortcuts_model_filter_drag_source_iface_init));
+                                               shortcuts_model_drag_source_iface_init));
 
-static GtkTreeModel *shortcuts_model_filter_new (GtkPlacesSidebar *sidebar,
-                                                GtkTreeModel          *child_model,
-                                                GtkTreePath           *root);
+static GtkListStore *shortcuts_model_new (GtkPlacesSidebar *sidebar);
 
 G_DEFINE_TYPE (GtkPlacesSidebar, gtk_places_sidebar, GTK_TYPE_SCROLLED_WINDOW);
 
@@ -275,42 +291,6 @@ get_icon_size (GtkPlacesSidebar *sidebar)
                return 16;
 }
 
-static GdkPixbuf *
-get_eject_icon (GtkPlacesSidebar *sidebar,
-               gboolean highlighted)
-{
-       GdkPixbuf *eject;
-       GtkIconInfo *icon_info;
-       GIcon *icon;
-       int icon_size;
-       GtkIconTheme *icon_theme;
-       GtkStyleContext *style;
-
-       icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (sidebar)));
-       icon_size = get_icon_size (sidebar);
-       icon = g_themed_icon_new_with_default_fallbacks (ICON_NAME_EJECT);
-       icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon, icon_size, 0);
-
-       style = gtk_widget_get_style_context (GTK_WIDGET (sidebar));
-
-       gtk_style_context_save (style);
-
-       if (highlighted)
-               gtk_style_context_set_state (style, GTK_STATE_FLAG_PRELIGHT);
-
-       eject = gtk_icon_info_load_symbolic_for_context (icon_info,
-                                                        style,
-                                                        NULL,
-                                                        NULL);
-
-       gtk_style_context_restore (style);
-
-       g_object_unref (icon);
-       gtk_icon_info_free (icon_info);
-
-       return eject;
-}
-
 #if 0
 /* FIXME: remove this?  Let's allow the user to bookmark whatever he damn well pleases */
 static gboolean
@@ -323,6 +303,11 @@ is_built_in_bookmark (NautilusFile *file)
                return TRUE;
        }
 
+       if (nautilus_file_is_desktop_directory (file) &&
+           !g_settings_get_boolean (gnome_background_preferences, NAUTILUS_PREFERENCES_SHOW_DESKTOP)) {
+               return FALSE;
+       }
+
        built_in = FALSE;
 
        for (idx = 0; idx < G_USER_N_DIRECTORIES; idx++) {
@@ -345,7 +330,7 @@ add_heading (GtkPlacesSidebar *sidebar,
             SectionType section_type,
             const gchar *title)
 {
-       GtkTreeIter iter, child_iter;
+       GtkTreeIter iter;
 
        gtk_list_store_append (sidebar->store, &iter);
        gtk_list_store_set (sidebar->store, &iter,
@@ -356,12 +341,7 @@ add_heading (GtkPlacesSidebar *sidebar,
                            PLACES_SIDEBAR_COLUMN_NO_EJECT, TRUE,
                            -1);
 
-       gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (sidebar->filter_model));
-       gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (sidebar->filter_model),
-                                                         &child_iter,
-                                                         &iter);
-
-       return child_iter;
+       return iter;
 }
 
 static void
@@ -390,25 +370,7 @@ check_heading_for_section (GtkPlacesSidebar *sidebar,
        }
 }
 
-static GdkPixbuf *
-get_pixbuf_from_gicon (GtkPlacesSidebar *sidebar, GIcon *icon)
-{
-       int icon_size;
-       GtkIconTheme *icon_theme;
-       GtkIconInfo *icon_info;
-       GdkPixbuf *pixbuf;
-
-       icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (sidebar)));
-       icon_size = get_icon_size (sidebar);
-       icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon, icon_size, 0);
-
-       pixbuf = gtk_icon_info_load_icon (icon_info, NULL); /* NULL-GError */
-       gtk_icon_info_free (icon_info);
-
-       return pixbuf;
-}
-
-static GtkTreeIter
+static void
 add_place (GtkPlacesSidebar *sidebar,
           PlaceType place_type,
           SectionType section_type,
@@ -421,16 +383,13 @@ add_place (GtkPlacesSidebar *sidebar,
           const int index,
           const char *tooltip)
 {
-       GdkPixbuf            *pixbuf;
-       GtkTreeIter           iter, child_iter;
-       GdkPixbuf            *eject;
+       GtkTreeIter           iter;
+       GIcon *eject;
        gboolean show_eject, show_unmount;
        gboolean show_eject_button;
 
        check_heading_for_section (sidebar, section_type);
 
-       pixbuf = get_pixbuf_from_gicon (sidebar, icon);
-
        check_unmount_and_eject (mount, volume, drive,
                                 &show_unmount, &show_eject);
 
@@ -445,14 +404,14 @@ add_place (GtkPlacesSidebar *sidebar,
        }
 
        if (show_eject_button) {
-               eject = get_eject_icon (sidebar, FALSE);
+               eject = g_themed_icon_new_with_default_fallbacks ("media-eject-symbolic");
        } else {
                eject = NULL;
        }
 
        gtk_list_store_append (sidebar->store, &iter);
        gtk_list_store_set (sidebar->store, &iter,
-                           PLACES_SIDEBAR_COLUMN_ICON, pixbuf,
+                           PLACES_SIDEBAR_COLUMN_GICON, icon,
                            PLACES_SIDEBAR_COLUMN_NAME, name,
                            PLACES_SIDEBAR_COLUMN_URI, uri,
                            PLACES_SIDEBAR_COLUMN_DRIVE, drive,
@@ -464,68 +423,78 @@ add_place (GtkPlacesSidebar *sidebar,
                            PLACES_SIDEBAR_COLUMN_NO_EJECT, !show_eject_button,
                            PLACES_SIDEBAR_COLUMN_BOOKMARK, place_type != PLACES_BOOKMARK,
                            PLACES_SIDEBAR_COLUMN_TOOLTIP, tooltip,
-                           PLACES_SIDEBAR_COLUMN_EJECT_ICON, eject,
+                           PLACES_SIDEBAR_COLUMN_EJECT_GICON, eject,
                            PLACES_SIDEBAR_COLUMN_SECTION_TYPE, section_type,
                            -1);
 
-       if (pixbuf != NULL) {
-               g_object_unref (pixbuf);
+       if (eject != NULL) {
+               g_object_unref (eject);
        }
-       gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (sidebar->filter_model));
-       gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (sidebar->filter_model),
-                                                         &child_iter,
-                                                         &iter);
-       return child_iter;
 }
 
-static void
-compare_for_selection (GtkPlacesSidebar *sidebar,
-                      const gchar *location,
-                      const gchar *added_uri,
-                      const gchar *last_uri,
-                      GtkTreeIter *iter,
-                      GtkTreePath **path)
+typedef struct {
+       const gchar *location;
+       const gchar *last_uri;
+       GtkPlacesSidebar *sidebar;
+       GtkTreePath *path;
+} RestoreLocationData;
+
+static gboolean
+restore_selection_foreach (GtkTreeModel *model,
+                          GtkTreePath *path,
+                          GtkTreeIter *iter,
+                          gpointer user_data)
 {
-       int res;
+       RestoreLocationData *data = user_data;
+       gchar *uri;
 
-       res = g_strcmp0 (added_uri, last_uri);
+       gtk_tree_model_get (model, iter,
+                           PLACES_SIDEBAR_COLUMN_URI, &uri,
+                           -1);
 
-       if (res == 0) {
-               /* last_uri always comes first */
-               if (*path != NULL) {
-                       gtk_tree_path_free (*path);
-               }
-               *path = gtk_tree_model_get_path (sidebar->filter_model,
-                                                iter);
-       } else if (g_strcmp0 (location, added_uri) == 0) {
-               if (*path == NULL) {
-                       *path = gtk_tree_model_get_path (sidebar->filter_model,
-                                                        iter);
-               }
+       if (g_strcmp0 (uri, data->last_uri) == 0 ||
+           g_strcmp0 (uri, data->location) == 0) {
+               data->path = gtk_tree_path_copy (path);
        }
+
+       g_free (uri);
+
+       return (data->path != NULL);
 }
 
-static char *
-get_home_directory_uri (void)
+static void
+sidebar_update_restore_selection (GtkPlacesSidebar *sidebar,
+                                 const gchar *location,
+                                 const gchar *last_uri)
 {
-       const char *home;
+       RestoreLocationData data;
+       GtkTreeSelection *selection;
 
-       home = g_get_home_dir ();
-       if (!home)
-               return NULL;
+       data.location = location;
+       data.last_uri = last_uri;
+       data.sidebar = sidebar;
+       data.path = NULL;
 
-       return g_strconcat ("file://", home, NULL);
+       gtk_tree_model_foreach (GTK_TREE_MODEL (sidebar->store),
+                               restore_selection_foreach, &data);
+
+       if (data.path != NULL) {
+               selection = gtk_tree_view_get_selection (sidebar->tree_view);
+               gtk_tree_selection_select_path (selection, data.path);
+               gtk_tree_path_free (data.path);
+       }
 }
 
 static GIcon *
-get_gicon_for_user_special_directory (GUserDirectory directory)
+special_directory_get_gicon (GUserDirectory directory)
 {
-       #define ICON_CASE(x) \
-               case G_USER_DIRECTORY_ ## x:\
-                       return g_themed_icon_new (ICON_NAME_FOLDER_ ## x);
+
+#define ICON_CASE(x)                           \
+       case G_USER_DIRECTORY_ ## x:                                    \
+               return g_themed_icon_new (ICON_NAME_FOLDER_ ## x);
 
        switch (directory) {
-               ICON_CASE (DESKTOP);
+
                ICON_CASE (DOCUMENTS);
                ICON_CASE (DOWNLOAD);
                ICON_CASE (MUSIC);
@@ -535,14 +504,101 @@ get_gicon_for_user_special_directory (GUserDirectory directory)
                ICON_CASE (VIDEOS);
 
        default:
-               return g_themed_icon_new ("folder");
+               return g_themed_icon_new ("folder-symbolic");
+       }
+
+#undef ICON_CASE
+}
+
+static gboolean
+recent_is_supported (void)
+{
+       const char * const *supported;
+       int i;
+
+       supported = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
+       if (!supported) {
+               return FALSE;
        }
 
-       #undef ICON_CASE
+       for (i = 0; supported[i] != NULL; i++) {
+               if (strcmp ("recent", supported[i]) == 0) {
+                       return TRUE;
+               }
+       }
+       return FALSE;
 }
 
-static const char *
-get_desktop_directory (void)
+static void
+add_special_dirs (GtkPlacesSidebar *sidebar)
+{
+       GList *dirs;
+       int index;
+
+       dirs = NULL;
+       for (index = 0; index < G_USER_N_DIRECTORIES; index++) {
+               const char *path;
+               GFile *root;
+               GIcon *icon;
+               char *name;
+               char *mount_uri;
+               char *tooltip;
+
+               if (index == G_USER_DIRECTORY_DESKTOP ||
+                   index == G_USER_DIRECTORY_TEMPLATES ||
+                   index == G_USER_DIRECTORY_PUBLIC_SHARE) {
+                       continue;
+               }
+
+               path = g_get_user_special_dir (index);
+
+               /* xdg resets special dirs to the home directory in case
+                * it's not finiding what it expects. We don't want the home
+                * to be added multiple times in that weird configuration.
+                */
+               if (path == NULL
+                   || g_strcmp0 (path, g_get_home_dir ()) == 0
+                   || g_list_find_custom (dirs, path, (GCompareFunc) g_strcmp0) != NULL) {
+                       continue;
+               }
+
+               root = g_file_new_for_path (path);
+               name = g_file_get_basename (root);
+               icon = special_directory_get_gicon (index);
+               mount_uri = g_file_get_uri (root);
+               tooltip = g_file_get_parse_name (root);
+
+               add_place (sidebar, PLACES_XDG_DIR,
+                          SECTION_COMPUTER,
+                          name, icon, mount_uri,
+                          NULL, NULL, NULL, 0,
+                          tooltip);
+               g_free (name);
+               g_object_unref (root);
+               g_object_unref (icon);
+               g_free (mount_uri);
+               g_free (tooltip);
+
+               dirs = g_list_prepend (dirs, (char *)path);
+       }
+
+       g_list_free (dirs);
+}
+
+static char *
+get_home_directory_uri (void)
+{
+       const char *home;
+
+       home = g_get_home_dir ();
+       if (!home)
+               return NULL;
+
+       return g_strconcat ("file://", home, NULL);
+}
+
+static char *
+get_desktop_directory_uri (void)
 {
        const char *name;
 
@@ -553,7 +609,7 @@ get_desktop_directory (void)
        if (!g_strcmp0 (name, g_get_home_dir ())) {
                return NULL;
        } else {
-               return name;
+               return g_strconcat ("file://", name, NULL);
        }
 }
 
@@ -562,7 +618,6 @@ update_places (GtkPlacesSidebar *sidebar)
 {
        GtkTreeSelection *selection;
        GtkTreeIter last_iter;
-       GtkTreePath *select_path;
        GtkTreeModel *model;
        GVolumeMonitor *volume_monitor;
        GList *mounts, *l, *ll;
@@ -573,18 +628,15 @@ update_places (GtkPlacesSidebar *sidebar)
        GVolume *volume;
        GSList *bookmarks, *sl;
        int index;
-       const char *desktop_path;
-       char *mount_uri, *name, *last_uri;
+       char *location, *mount_uri, *name, *last_uri, *identifier;
        char *bookmark_name;
-       const gchar *path;
        GIcon *icon;
        GFile *root;
        char *tooltip;
-       GList *network_mounts;
+       GList *network_mounts, *network_volumes;
 
        model = NULL;
        last_uri = NULL;
-       select_path = NULL;
 
        selection = gtk_tree_view_get_selection (sidebar->tree_view);
        if (gtk_tree_selection_get_selected (selection, &model, &last_iter)) {
@@ -597,9 +649,72 @@ update_places (GtkPlacesSidebar *sidebar)
        sidebar->devices_header_added = FALSE;
        sidebar->bookmarks_header_added = FALSE;
 
+#if 0
+       /* FIXME: the "location" is used at the end of this function
+        * to restore the current location.  How do we do that now?
+        */
+       slot = nautilus_window_get_active_slot (sidebar->window);
+       location = nautilus_window_slot_get_current_uri (slot);
+#else
+       location = NULL;
+#endif
+
+       network_mounts = network_volumes = NULL;
        volume_monitor = sidebar->volume_monitor;
 
-       /* first go through all connected drives */
+       /* add built in bookmarks */
+
+       add_heading (sidebar, SECTION_COMPUTER,
+                    _("Places"));
+
+       if (recent_is_supported ()) {
+               mount_uri = "recent:///"; /* No need to strdup */
+               icon = g_themed_icon_new ("document-open-recent-symbolic");
+               add_place (sidebar, PLACES_BUILT_IN,
+                          SECTION_COMPUTER,
+                          _("Recent"), icon, mount_uri,
+                          NULL, NULL, NULL, 0,
+                          _("Recent files"));
+               g_object_unref (icon);
+       }
+
+       /* home folder */
+       mount_uri = get_home_directory_uri ();
+       icon = g_themed_icon_new (ICON_NAME_HOME);
+       add_place (sidebar, PLACES_BUILT_IN,
+                  SECTION_COMPUTER,
+                  _("Home"), icon,
+                  mount_uri, NULL, NULL, NULL, 0,
+                  _("Open your personal folder"));
+       g_object_unref (icon);
+       g_free (mount_uri);
+
+       if (sidebar->show_desktop) {
+               /* desktop */
+               mount_uri = get_desktop_directory_uri ();
+               icon = g_themed_icon_new (ICON_NAME_DESKTOP);
+               add_place (sidebar, PLACES_BUILT_IN,
+                          SECTION_COMPUTER,
+                          _("Desktop"), icon,
+                          mount_uri, NULL, NULL, NULL, 0,
+                          _("Open the contents of your desktop in a folder"));
+               g_object_unref (icon);
+               g_free (mount_uri);
+       }
+
+       /* XDG directories */
+       add_special_dirs (sidebar);
+
+       mount_uri = "trash:///"; /* No need to strdup */
+       icon = g_themed_icon_new (ICON_NAME_TRASH);
+       add_place (sidebar, PLACES_BUILT_IN,
+                  SECTION_COMPUTER,
+                  _("Trash"), icon, mount_uri,
+                  NULL, NULL, NULL, 0,
+                  _("Open the trash"));
+       g_object_unref (icon);
+
+       /* go through all connected drives */
        drives = g_volume_monitor_get_connected_drives (volume_monitor);
 
        for (l = drives; l != NULL; l = l->next) {
@@ -609,22 +724,28 @@ update_places (GtkPlacesSidebar *sidebar)
                if (volumes != NULL) {
                        for (ll = volumes; ll != NULL; ll = ll->next) {
                                volume = ll->data;
+                               identifier = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_CLASS);
+
+                               if (g_strcmp0 (identifier, "network") == 0) {
+                                       g_free (identifier);
+                                       network_volumes = g_list_prepend (network_volumes, volume);
+                                       continue;
+                               }
+                               g_free (identifier);
+
                                mount = g_volume_get_mount (volume);
                                if (mount != NULL) {
                                        /* Show mounted volume in the sidebar */
-                                       icon = g_mount_get_icon (mount);
+                                       icon = g_mount_get_symbolic_icon (mount);
                                        root = g_mount_get_default_location (mount);
                                        mount_uri = g_file_get_uri (root);
                                        name = g_mount_get_name (mount);
                                        tooltip = g_file_get_parse_name (root);
 
-                                       last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
-                                                              SECTION_DEVICES,
-                                                              name, icon, mount_uri,
-                                                              drive, volume, mount, 0, tooltip);
-                                       compare_for_selection (sidebar,
-                                                              sidebar->uri, mount_uri, last_uri,
-                                                              &last_iter, &select_path);
+                                       add_place (sidebar, PLACES_MOUNTED_VOLUME,
+                                                  SECTION_DEVICES,
+                                                  name, icon, mount_uri,
+                                                  drive, volume, mount, 0, tooltip);
                                        g_object_unref (root);
                                        g_object_unref (mount);
                                        g_object_unref (icon);
@@ -640,14 +761,14 @@ update_places (GtkPlacesSidebar *sidebar)
                                         * cue that the user should remember to yank out the media if
                                         * he just unmounted it.
                                         */
-                                       icon = g_volume_get_icon (volume);
+                                       icon = g_volume_get_symbolic_icon (volume);
                                        name = g_volume_get_name (volume);
                                        tooltip = g_strdup_printf (_("Mount and open %s"), name);
 
-                                       last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
-                                                              SECTION_DEVICES,
-                                                              name, icon, NULL,
-                                                              drive, volume, NULL, 0, tooltip);
+                                       add_place (sidebar, PLACES_MOUNTED_VOLUME,
+                                                  SECTION_DEVICES,
+                                                  name, icon, NULL,
+                                                  drive, volume, NULL, 0, tooltip);
                                        g_object_unref (icon);
                                        g_free (name);
                                        g_free (tooltip);
@@ -665,14 +786,14 @@ update_places (GtkPlacesSidebar *sidebar)
                                 * work.. but it's also for human beings who like to turn off media detection
                                 * in the OS to save battery juice.
                                 */
-                               icon = g_drive_get_icon (drive);
+                               icon = g_drive_get_symbolic_icon (drive);
                                name = g_drive_get_name (drive);
                                tooltip = g_strdup_printf (_("Mount and open %s"), name);
 
-                               last_iter = add_place (sidebar, PLACES_BUILT_IN,
-                                                      SECTION_DEVICES,
-                                                      name, icon, NULL,
-                                                      drive, NULL, NULL, 0, tooltip);
+                               add_place (sidebar, PLACES_BUILT_IN,
+                                          SECTION_DEVICES,
+                                          name, icon, NULL,
+                                          drive, NULL, NULL, 0, tooltip);
                                g_object_unref (icon);
                                g_free (tooltip);
                                g_free (name);
@@ -692,21 +813,28 @@ update_places (GtkPlacesSidebar *sidebar)
                        g_object_unref (drive);
                        continue;
                }
+
+               identifier = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_CLASS);
+
+               if (g_strcmp0 (identifier, "network") == 0) {
+                       g_free (identifier);
+                       network_volumes = g_list_prepend (network_volumes, volume);
+                       continue;
+               }
+               g_free (identifier);
+
                mount = g_volume_get_mount (volume);
                if (mount != NULL) {
-                       icon = g_mount_get_icon (mount);
+                       icon = g_mount_get_symbolic_icon (mount);
                        root = g_mount_get_default_location (mount);
                        mount_uri = g_file_get_uri (root);
                        tooltip = g_file_get_parse_name (root);
                        g_object_unref (root);
                        name = g_mount_get_name (mount);
-                       last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
-                                              SECTION_DEVICES,
-                                              name, icon, mount_uri,
-                                              NULL, volume, mount, 0, tooltip);
-                       compare_for_selection (sidebar,
-                                              sidebar->uri, mount_uri, last_uri,
-                                              &last_iter, &select_path);
+                       add_place (sidebar, PLACES_MOUNTED_VOLUME,
+                                  SECTION_DEVICES,
+                                  name, icon, mount_uri,
+                                  NULL, volume, mount, 0, tooltip);
                        g_object_unref (mount);
                        g_object_unref (icon);
                        g_free (name);
@@ -714,12 +842,12 @@ update_places (GtkPlacesSidebar *sidebar)
                        g_free (mount_uri);
                } else {
                        /* see comment above in why we add an icon for an unmounted mountable volume */
-                       icon = g_volume_get_icon (volume);
+                       icon = g_volume_get_symbolic_icon (volume);
                        name = g_volume_get_name (volume);
-                       last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
-                                              SECTION_DEVICES,
-                                              name, icon, NULL,
-                                              NULL, volume, NULL, 0, name);
+                       add_place (sidebar, PLACES_MOUNTED_VOLUME,
+                                  SECTION_DEVICES,
+                                  name, icon, NULL,
+                                  NULL, volume, NULL, 0, name);
                        g_object_unref (icon);
                        g_free (name);
                }
@@ -727,6 +855,56 @@ update_places (GtkPlacesSidebar *sidebar)
        }
        g_list_free (volumes);
 
+       /* file system root */
+
+       mount_uri = "file:///"; /* No need to strdup */
+       icon = g_themed_icon_new (ICON_NAME_FILESYSTEM);
+       add_place (sidebar, PLACES_BUILT_IN,
+                  SECTION_DEVICES,
+                  sidebar->hostname, icon,
+                  mount_uri, NULL, NULL, NULL, 0,
+                  _("Open the contents of the File System"));
+       g_object_unref (icon);
+
+       /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
+       mounts = g_volume_monitor_get_mounts (volume_monitor);
+
+       for (l = mounts; l != NULL; l = l->next) {
+               mount = l->data;
+               if (g_mount_is_shadowed (mount)) {
+                       g_object_unref (mount);
+                       continue;
+               }
+               volume = g_mount_get_volume (mount);
+               if (volume != NULL) {
+                       g_object_unref (volume);
+                       g_object_unref (mount);
+                       continue;
+               }
+               root = g_mount_get_default_location (mount);
+
+               if (!g_file_is_native (root)) {
+                       network_mounts = g_list_prepend (network_mounts, mount);
+                       continue;
+               }
+
+               icon = g_mount_get_symbolic_icon (mount);
+               mount_uri = g_file_get_uri (root);
+               name = g_mount_get_name (mount);
+               tooltip = g_file_get_parse_name (root);
+               add_place (sidebar, PLACES_MOUNTED_VOLUME,
+                          SECTION_COMPUTER,
+                          name, icon, mount_uri,
+                          NULL, NULL, mount, 0, tooltip);
+               g_object_unref (root);
+               g_object_unref (mount);
+               g_object_unref (icon);
+               g_free (name);
+               g_free (mount_uri);
+               g_free (tooltip);
+       }
+       g_list_free (mounts);
+
        /* add bookmarks */
 
        bookmarks = _gtk_bookmarks_manager_list_bookmarks (sidebar->bookmarks_manager);
@@ -755,20 +933,19 @@ update_places (GtkPlacesSidebar *sidebar)
 #endif
 
                bookmark_name = _gtk_bookmarks_manager_get_bookmark_label (sidebar->bookmarks_manager, root);
+               icon = NULL; /* FIXME: icon = nautilus_bookmark_get_icon (bookmark); */
                mount_uri = g_file_get_uri (root);
                tooltip = g_file_get_parse_name (root);
-               icon = NULL; /* FIXME: icon = nautilus_bookmark_get_icon (bookmark); */
 
-               last_iter = add_place (sidebar, PLACES_BOOKMARK,
-                                      SECTION_BOOKMARKS,
-                                      bookmark_name, icon, mount_uri,
-                                      NULL, NULL, NULL, index,
-                                      tooltip);
-               compare_for_selection (sidebar,
-                                      sidebar->uri, mount_uri, last_uri,
-                                      &last_iter, &select_path);
+               add_place (sidebar, PLACES_BOOKMARK,
+                          SECTION_BOOKMARKS,
+                          bookmark_name, icon, mount_uri,
+                          NULL, NULL, NULL, index,
+                          tooltip);
+
+               if (icon)
+                       g_object_unref (icon);
 
-               g_object_unref (icon);
                g_free (mount_uri);
                g_free (tooltip);
                g_free (bookmark_name);
@@ -777,171 +954,56 @@ update_places (GtkPlacesSidebar *sidebar)
        g_slist_foreach (bookmarks, (GFunc) g_object_unref, NULL);
        g_slist_free (bookmarks);
 
-       last_iter = add_heading (sidebar, SECTION_COMPUTER,
-                              _("Computer"));
-
-       /* add built in bookmarks */
-
-       /* home folder */
-       mount_uri = get_home_directory_uri ();
-       if (mount_uri) {
-               icon = g_themed_icon_new (ICON_NAME_HOME);
-               last_iter = add_place (sidebar, PLACES_BUILT_IN,
-                                      SECTION_COMPUTER,
-                                      _("Home"), icon,
-                                      mount_uri, NULL, NULL, NULL, 0,
-                                      _("Open your personal folder"));
-               g_object_unref (icon);
-               compare_for_selection (sidebar,
-                                      sidebar->uri, mount_uri, last_uri,
-                                      &last_iter, &select_path);
-               g_free (mount_uri);
-       }
-
-       desktop_path = get_desktop_directory ();
-       if (sidebar->show_desktop && desktop_path) {
-               /* desktop */
-               mount_uri = g_filename_to_uri (desktop_path, NULL, NULL);
-               icon = g_themed_icon_new (ICON_NAME_DESKTOP);
-               last_iter = add_place (sidebar, PLACES_BUILT_IN,
-                                      SECTION_COMPUTER,
-                                      _("Desktop"), icon,
-                                      mount_uri, NULL, NULL, NULL, 0,
-                                      _("Open the contents of your desktop in a folder"));
-               g_object_unref (icon);
-               compare_for_selection (sidebar,
-                                      sidebar->uri, mount_uri, last_uri,
-                                      &last_iter, &select_path);
-               g_free (mount_uri);
-       }
-
-       /* XDG directories */
-       for (index = 0; index < G_USER_N_DIRECTORIES; index++) {
-
-               if (index == G_USER_DIRECTORY_DESKTOP ||
-                   index == G_USER_DIRECTORY_TEMPLATES ||
-                   index == G_USER_DIRECTORY_PUBLIC_SHARE) {
-                       continue;
-               }
-
-               path = g_get_user_special_dir (index);
-
-               /* xdg resets special dirs to the home directory in case
-                * it's not finiding what it expects. We don't want the home
-                * to be added multiple times in that weird configuration.
-                */
-               if (!path || g_strcmp0 (path, g_get_home_dir ()) == 0) {
-                       continue;
-               }
-
-               root = g_file_new_for_path (path);
-               name = g_file_get_basename (root);
-               icon = get_gicon_for_user_special_directory (index);
-               mount_uri = g_file_get_uri (root);
-               tooltip = g_file_get_parse_name (root);
+       /* network */
+       add_heading (sidebar, SECTION_NETWORK,
+                    _("Network"));
 
-               last_iter = add_place (sidebar, PLACES_BUILT_IN,
-                                      SECTION_COMPUTER,
-                                      name, icon, mount_uri,
-                                      NULL, NULL, NULL, 0,
-                                      tooltip);
-               compare_for_selection (sidebar,
-                                      sidebar->uri, mount_uri, last_uri,
-                                      &last_iter, &select_path);
-               g_free (name);
-               g_object_unref (root);
-               g_object_unref (icon);
-               g_free (mount_uri);
-               g_free (tooltip);
-       }
+       mount_uri = "network:///"; /* No need to strdup */
+       icon = g_themed_icon_new (ICON_NAME_NETWORK);
+       add_place (sidebar, PLACES_BUILT_IN,
+                  SECTION_NETWORK,
+                  _("Browse Network"), icon,
+                  mount_uri, NULL, NULL, NULL, 0,
+                  _("Browse the contents of the network"));
+       g_object_unref (icon);
 
-       /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
-       network_mounts = NULL;
-       mounts = g_volume_monitor_get_mounts (volume_monitor);
+       network_volumes = g_list_reverse (network_volumes);
+       for (l = network_volumes; l != NULL; l = l->next) {
+               volume = l->data;
+               mount = g_volume_get_mount (volume);
 
-       for (l = mounts; l != NULL; l = l->next) {
-               mount = l->data;
-               if (g_mount_is_shadowed (mount)) {
-                       g_object_unref (mount);
-                       continue;
-               }
-               volume = g_mount_get_volume (mount);
-               if (volume != NULL) {
-                       g_object_unref (volume);
-                       g_object_unref (mount);
+               if (mount != NULL) {
+                       network_mounts = g_list_prepend (network_mounts, mount);
                        continue;
-               }
-               root = g_mount_get_default_location (mount);
+               } else {
+                       icon = g_volume_get_symbolic_icon (volume);
+                       name = g_volume_get_name (volume);
+                       tooltip = g_strdup_printf (_("Mount and open %s"), name);
 
-               if (!g_file_is_native (root)) {
-                       network_mounts = g_list_prepend (network_mounts, g_object_ref (mount));
-                       continue;
+                       add_place (sidebar, PLACES_MOUNTED_VOLUME,
+                                  SECTION_NETWORK,
+                                  name, icon, NULL,
+                                  NULL, volume, NULL, 0, tooltip);
+                       g_object_unref (icon);
+                       g_free (name);
+                       g_free (tooltip);
                }
-
-               icon = g_mount_get_icon (mount);
-               mount_uri = g_file_get_uri (root);
-               name = g_mount_get_name (mount);
-               tooltip = g_file_get_parse_name (root);
-               last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
-                                      SECTION_COMPUTER,
-                                      name, icon, mount_uri,
-                                      NULL, NULL, mount, 0, tooltip);
-               compare_for_selection (sidebar,
-                                      sidebar->uri, mount_uri, last_uri,
-                                      &last_iter, &select_path);
-               g_object_unref (root);
-               g_object_unref (mount);
-               g_object_unref (icon);
-               g_free (name);
-               g_free (mount_uri);
-               g_free (tooltip);
        }
-       g_list_free (mounts);
 
-       /* file system root */
-       mount_uri = "file:///"; /* No need to strdup */
-       icon = g_themed_icon_new (ICON_NAME_FILESYSTEM);
-       last_iter = add_place (sidebar, PLACES_BUILT_IN,
-                              SECTION_COMPUTER,
-                              _("File System"), icon,
-                              mount_uri, NULL, NULL, NULL, 0,
-                              _("Open the contents of the File System"));
-       g_object_unref (icon);
-       compare_for_selection (sidebar,
-                              sidebar->uri, mount_uri, last_uri,
-                              &last_iter, &select_path);
-
-       mount_uri = "trash:///"; /* No need to strdup */
-       icon = g_themed_icon_new (ICON_NAME_TRASH);
-       last_iter = add_place (sidebar, PLACES_BUILT_IN,
-                              SECTION_COMPUTER,
-                              _("Trash"), icon, mount_uri,
-                              NULL, NULL, NULL, 0,
-                              _("Open the trash"));
-       compare_for_selection (sidebar,
-                              sidebar->uri, mount_uri, last_uri,
-                              &last_iter, &select_path);
-       g_object_unref (icon);
-
-       /* network */
-       last_iter = add_heading (sidebar, SECTION_NETWORK,
-                                _("Network"));
+       g_list_free_full (network_volumes, g_object_unref);
 
        network_mounts = g_list_reverse (network_mounts);
        for (l = network_mounts; l != NULL; l = l->next) {
                mount = l->data;
                root = g_mount_get_default_location (mount);
-               icon = g_mount_get_icon (mount);
+               icon = g_mount_get_symbolic_icon (mount);
                mount_uri = g_file_get_uri (root);
                name = g_mount_get_name (mount);
                tooltip = g_file_get_parse_name (root);
-               last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
-                                      SECTION_NETWORK,
-                                      name, icon, mount_uri,
-                                      NULL, NULL, mount, 0, tooltip);
-               compare_for_selection (sidebar,
-                                      sidebar->uri, mount_uri, last_uri,
-                                      &last_iter, &select_path);
+               add_place (sidebar, PLACES_MOUNTED_VOLUME,
+                          SECTION_NETWORK,
+                          name, icon, mount_uri,
+                          NULL, NULL, mount, 0, tooltip);
                g_object_unref (root);
                g_object_unref (mount);
                g_object_unref (icon);
@@ -952,27 +1014,10 @@ update_places (GtkPlacesSidebar *sidebar)
 
        g_list_free_full (network_mounts, g_object_unref);
 
-       /* network:// */
-       mount_uri = "network:///"; /* No need to strdup */
-       icon = g_themed_icon_new (ICON_NAME_NETWORK);
-       last_iter = add_place (sidebar, PLACES_BUILT_IN,
-                              SECTION_NETWORK,
-                              _("Browse Network"), icon,
-                              mount_uri, NULL, NULL, NULL, 0,
-                              _("Browse the contents of the network"));
-       g_object_unref (icon);
-       compare_for_selection (sidebar,
-                              sidebar->uri, mount_uri, last_uri,
-                              &last_iter, &select_path);
-
-       if (select_path != NULL) {
-               gtk_tree_selection_select_path (selection, select_path);
-       }
-
-       if (select_path != NULL) {
-               gtk_tree_path_free (select_path);
-       }
+       /* restore selection */
+       sidebar_update_restore_selection (sidebar, location, last_uri);
 
+       g_free (location);
        g_free (last_uri);
 }
 
@@ -1129,12 +1174,12 @@ clicked_eject_button (GtkPlacesSidebar *sidebar,
 
 /* Computes the appropriate row and position for dropping */
 static gboolean
-compute_drop_position (GtkTreeView *tree_view,
+compute_drop_position (GtkTreeView             *tree_view,
                       int                      x,
                       int                      y,
                       GtkTreePath            **path,
                       GtkTreeViewDropPosition *pos,
-                      GtkPlacesSidebar *sidebar)
+                      GtkPlacesSidebar        *sidebar)
 {
        GtkTreeModel *model;
        GtkTreeIter iter;
@@ -1142,10 +1187,8 @@ compute_drop_position (GtkTreeView *tree_view,
        SectionType section_type;
 
        if (!gtk_tree_view_get_dest_row_at_pos (tree_view,
-                                          x,
-                                          y,
-                                          path,
-                                          pos)) {
+                                               x, y,
+                                               path, pos)) {
                return FALSE;
        }
 
@@ -1157,9 +1200,11 @@ compute_drop_position (GtkTreeView *tree_view,
                            PLACES_SIDEBAR_COLUMN_SECTION_TYPE, &section_type,
                            -1);
 
-       if (place_type == PLACES_HEADING && section_type != SECTION_BOOKMARKS) {
+       if (section_type != SECTION_BOOKMARKS &&
+           place_type == PLACES_HEADING) {
                /* never drop on headings, but special case the bookmarks heading,
-                * so we can drop bookmarks in between it and the first item.
+                * so we can drop bookmarks in between it and the first item when
+                * reordering.
                 */
 
                gtk_tree_path_free (*path);
@@ -1172,27 +1217,20 @@ compute_drop_position (GtkTreeView *tree_view,
            sidebar->drag_data_received &&
            sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
                /* don't allow dropping bookmarks into non-bookmark areas */
-
                gtk_tree_path_free (*path);
                *path = NULL;
 
                return FALSE;
        }
 
-       if (section_type == SECTION_BOOKMARKS) {
+       if (sidebar->drag_data_received &&
+           sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
+               /* bookmark rows can only be reordered */
                *pos = GTK_TREE_VIEW_DROP_AFTER;
        } else {
-               /* non-bookmark shortcuts can only be dragged into */
                *pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
        }
 
-       if (*pos != GTK_TREE_VIEW_DROP_BEFORE &&
-           sidebar->drag_data_received &&
-           sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
-               /* bookmark rows are never dragged into other bookmark rows */
-               *pos = GTK_TREE_VIEW_DROP_AFTER;
-       }
-
        return TRUE;
 }
 
@@ -1230,39 +1268,6 @@ free_drag_data (GtkPlacesSidebar *sidebar)
        }
 }
 
-#if 0
-/* FIXME: remove this?  Let's allow the user to bookmark whatever he damn well pleases */
-static gboolean
-can_accept_file_as_bookmark (NautilusFile *file)
-{
-       return (nautilus_file_is_directory (file) &&
-               !is_built_in_bookmark (file));
-}
-
-static gboolean
-can_accept_items_as_bookmarks (const GList *items)
-{
-       int max;
-       char *uri;
-       NautilusFile *file;
-
-       /* Iterate through selection checking if item will get accepted as a bookmark.
-        * If more than 100 items selected, return an over-optimistic result.
-        */
-       for (max = 100; items != NULL && max >= 0; items = items->next, max--) {
-               uri = ((NautilusDragSelectionItem *)items->data)->uri;
-               file = nautilus_file_get_by_uri (uri);
-               if (!can_accept_file_as_bookmark (file)) {
-                       nautilus_file_unref (file);
-                       return FALSE;
-               }
-               nautilus_file_unref (file);
-       }
-
-       return TRUE;
-}
-#endif
-
 static gboolean
 drag_motion_callback (GtkTreeView *tree_view,
                      GdkDragContext *context,
@@ -1291,30 +1296,20 @@ drag_motion_callback (GtkTreeView *tree_view,
                goto out;
        }
 
-       if (pos == GTK_TREE_VIEW_DROP_BEFORE ||
-           pos == GTK_TREE_VIEW_DROP_AFTER ) {
+       if (pos == GTK_TREE_VIEW_DROP_AFTER ) {
                if (sidebar->drag_data_received &&
                    sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
                        action = GDK_ACTION_MOVE;
-               }
-#if 1
-               else
-                       action = GDK_ACTION_COPY;
-#else
-               /* FIXME: remove this?  Let's allow the user to bookmark whatever he damn well pleases */
-               else if (can_accept_items_as_bookmarks (sidebar->drag_list)) {
-                       action = GDK_ACTION_COPY;
                } else {
                        action = 0;
                }
-#endif
        } else {
                if (sidebar->drag_list == NULL) {
                        action = 0;
                } else {
-                       gtk_tree_model_get_iter (sidebar->filter_model,
+                       gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->store),
                                                 &iter, path);
-                       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model),
+                       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store),
                                            &iter,
                                            PLACES_SIDEBAR_COLUMN_URI, &uri,
                                            -1);
@@ -1354,48 +1349,10 @@ drag_leave_callback (GtkTreeView *tree_view,
                     GtkPlacesSidebar *sidebar)
 {
        free_drag_data (sidebar);
-       gtk_tree_view_set_drag_dest_row (tree_view, NULL, GTK_TREE_VIEW_DROP_BEFORE);
+       gtk_tree_view_set_drag_dest_row (tree_view, NULL, 0);
        g_signal_stop_emission_by_name (tree_view, "drag-leave");
 }
 
-/* Parses a "text/uri-list" string and inserts its URIs as bookmarks */
-static void
-bookmarks_drop_uris (GtkPlacesSidebar *sidebar,
-                    GtkSelectionData      *selection_data,
-                    int                    position)
-{
-       char **uris;
-       int i;
-
-       uris = gtk_selection_data_get_uris (selection_data);
-       if (!uris)
-               return;
-
-       for (i = 0; uris[i]; i++) {
-               char *uri;
-               GFile *location;
-
-               uri = uris[i];
-
-#if 0
-               /* FIXME: remove this?  Let's allow the user to bookmark whatever he damn well pleases */
-               if (!can_accept_file_as_bookmark (file)) {
-                       nautilus_file_unref (file);
-                       continue;
-               }
-#endif
-
-               location = g_file_new_for_uri (uri);
-
-               if (_gtk_bookmarks_manager_insert_bookmark (sidebar->bookmarks_manager, location, position, NULL)) /* NULL-GError */
-                       position++;
-
-               g_object_unref (location);
-       }
-
-       g_strfreev (uris);
-}
-
 static GList *
 uri_list_from_selection (GList *selection)
 {
@@ -1467,11 +1424,11 @@ reorder_bookmarks (GtkPlacesSidebar *sidebar,
        int old_position;
 
        /* Get the selected path */
+       if (!get_selected_iter (sidebar, &iter)) {
+               return;
+       }
 
-       if (!get_selected_iter (sidebar, &iter))
-               g_assert_not_reached ();
-
-       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                            PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
                            PLACES_SIDEBAR_COLUMN_INDEX, &old_position,
                            -1);
@@ -1515,7 +1472,7 @@ drag_data_received_callback (GtkWidget *widget,
        if (!sidebar->drag_data_received) {
                if (gtk_selection_data_get_target (selection_data) != GDK_NONE &&
                    info == TEXT_URI_LIST) {
-                       sidebar->drag_list = build_selection_list (gtk_selection_data_get_data (selection_data));
+                       sidebar->drag_list = build_selection_list ((const gchar *) gtk_selection_data_get_data (selection_data));
                } else {
                        sidebar->drag_list = NULL;
                }
@@ -1530,12 +1487,14 @@ drag_data_received_callback (GtkWidget *widget,
        }
 
        /* Compute position */
-       compute_drop_position (tree_view, x, y, &tree_path, &tree_pos, sidebar);
+       success = compute_drop_position (tree_view, x, y, &tree_path, &tree_pos, sidebar);
+       if (!success) {
+               goto out;
+       }
 
        success = FALSE;
 
-       if (tree_pos == GTK_TREE_VIEW_DROP_BEFORE ||
-           tree_pos == GTK_TREE_VIEW_DROP_AFTER) {
+       if (tree_pos == GTK_TREE_VIEW_DROP_AFTER) {
                model = gtk_tree_view_get_model (tree_view);
 
                if (!gtk_tree_model_get_iter (model, &iter, tree_path)) {
@@ -1558,10 +1517,6 @@ drag_data_received_callback (GtkWidget *widget,
                }
 
                switch (info) {
-               case TEXT_URI_LIST:
-                       bookmarks_drop_uris (sidebar, selection_data, position);
-                       success = TRUE;
-                       break;
                case GTK_TREE_MODEL_ROW:
                        reorder_bookmarks (sidebar, position);
                        success = TRUE;
@@ -1592,7 +1547,7 @@ drag_data_received_callback (GtkWidget *widget,
 
                        switch (info) {
                        case TEXT_URI_LIST:
-                               selection_list = build_selection_list (gtk_selection_data_get_data (selection_data));
+                               selection_list = build_selection_list ((const gchar *) gtk_selection_data_get_data (selection_data));
                                uris = uri_list_from_selection (selection_list);
                                nautilus_file_operations_copy_move (uris, NULL, drop_uri,
                                                                    real_action, GTK_WIDGET (tree_view),
@@ -1659,6 +1614,8 @@ bookmarks_popup_menu_detach_cb (GtkWidget *attach_widget,
        sidebar->popup_menu_start_item = NULL;
        sidebar->popup_menu_stop_item = NULL;
        sidebar->popup_menu_empty_trash_item = NULL;
+       sidebar->popup_menu_properties_separator_item = NULL;
+       sidebar->popup_menu_properties_item = NULL;
 }
 
 static void
@@ -1729,6 +1686,10 @@ bookmarks_check_popup_sensitivity (GtkPlacesSidebar *sidebar)
        GDrive *drive = NULL;
        GVolume *volume = NULL;
        GMount *mount = NULL;
+       GFile *location;
+#if DO_NOT_COMPILE
+       NautilusDirectory *directory;
+#endif
        gboolean show_mount;
        gboolean show_unmount;
        gboolean show_eject;
@@ -1736,6 +1697,7 @@ bookmarks_check_popup_sensitivity (GtkPlacesSidebar *sidebar)
        gboolean show_start;
        gboolean show_stop;
        gboolean show_empty_trash;
+       gboolean show_properties;
        char *uri = NULL;
 
        type = PLACES_BUILT_IN;
@@ -1745,7 +1707,7 @@ bookmarks_check_popup_sensitivity (GtkPlacesSidebar *sidebar)
        }
 
        if (get_selected_iter (sidebar, &iter)) {
-               gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+               gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                                    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
                                    PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
                                    PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
@@ -1772,6 +1734,22 @@ bookmarks_check_popup_sensitivity (GtkPlacesSidebar *sidebar)
        show_empty_trash = (uri != NULL) &&
                           (!strcmp (uri, "trash:///"));
 
+#if DO_NOT_COMPILE
+       /* Only show properties for local mounts */
+       show_properties = (mount != NULL);
+       if (mount != NULL) {
+               location = g_mount_get_default_location (mount);
+               directory = nautilus_directory_get (location);
+
+               show_properties = nautilus_directory_is_local (directory);
+
+               nautilus_directory_unref (directory);
+               g_object_unref (location);
+       }
+#else
+       show_properties = FALSE;
+#endif
+
        gtk_widget_set_visible (sidebar->popup_menu_separator_item,
                      show_mount || show_unmount || show_eject || show_empty_trash);
        gtk_widget_set_visible (sidebar->popup_menu_mount_item, show_mount);
@@ -1781,6 +1759,8 @@ bookmarks_check_popup_sensitivity (GtkPlacesSidebar *sidebar)
        gtk_widget_set_visible (sidebar->popup_menu_start_item, show_start);
        gtk_widget_set_visible (sidebar->popup_menu_stop_item, show_stop);
        gtk_widget_set_visible (sidebar->popup_menu_empty_trash_item, show_empty_trash);
+       gtk_widget_set_visible (sidebar->popup_menu_properties_separator_item, show_properties);
+       gtk_widget_set_visible (sidebar->popup_menu_properties_item, show_properties);
 
        /* Adjust start/stop items to reflect the type of the drive */
        gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_start_item), _("_Start"));
@@ -1935,15 +1915,15 @@ open_shortcut_from_menu (GtkPlacesSidebar *sidebar,
                         GtkPlacesOpenMode open_mode)
 {
        GtkTreeModel *model;
-       GtkTreePath *path;
        GtkTreeIter iter;
+       GtkTreePath *path = NULL;
 
        model = gtk_tree_view_get_model (sidebar->tree_view);
        gtk_tree_view_get_cursor (sidebar->tree_view, &path, NULL);
 
-       gtk_tree_model_get_iter (model, &iter, path);
-
-       open_selected_bookmark (sidebar, model, &iter, open_mode);
+       if (path != NULL && gtk_tree_model_get_iter (model, &iter, path)) {
+               open_selected_bookmark (sidebar, model, &iter, open_mode);
+       }
 
        gtk_tree_path_free (path);
 }
@@ -1977,20 +1957,24 @@ add_bookmark (GtkPlacesSidebar *sidebar)
        GtkTreeModel *model;
        GtkTreeIter iter;
        char *uri;
+       char *name;
        GFile *location;
        NautilusBookmark *bookmark;
 
        model = gtk_tree_view_get_model (sidebar->tree_view);
 
        if (get_selected_iter (sidebar, &iter)) {
-               gtk_tree_model_get (model, &iter, PLACES_SIDEBAR_COLUMN_URI, &uri, -1);
+               gtk_tree_model_get (model, &iter,
+                                   PLACES_SIDEBAR_COLUMN_URI, &uri,
+                                   PLACES_SIDEBAR_COLUMN_NAME, &name,
+                                   -1);
 
                if (uri == NULL) {
                        return;
                }
 
                location = g_file_new_for_uri (uri);
-               bookmark = nautilus_bookmark_new (location, NULL, NULL);
+               bookmark = nautilus_bookmark_new (location, name, NULL);
 
                if (!nautilus_bookmark_list_contains (sidebar->bookmarks, bookmark)) {
                        nautilus_bookmark_list_append (sidebar->bookmarks, bookmark);
@@ -1999,6 +1983,7 @@ add_bookmark (GtkPlacesSidebar *sidebar)
                g_object_unref (location);
                g_object_unref (bookmark);
                g_free (uri);
+               g_free (name);
        }
 #endif
 }
@@ -2022,7 +2007,7 @@ rename_selected_bookmark (GtkPlacesSidebar *sidebar)
        PlaceType type;
 
        if (get_selected_iter (sidebar, &iter)) {
-               gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+               gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                                    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
                                    -1);
 
@@ -2030,7 +2015,7 @@ rename_selected_bookmark (GtkPlacesSidebar *sidebar)
                        return;
                }
 
-               path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->filter_model), &iter);
+               path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &iter);
                column = gtk_tree_view_get_column (GTK_TREE_VIEW (sidebar->tree_view), 0);
                renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
                cell = g_list_nth_data (renderers, 6);
@@ -2062,7 +2047,7 @@ remove_selected_bookmarks (GtkPlacesSidebar *sidebar)
                return;
        }
 
-       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                            PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
                            -1);
 
@@ -2070,7 +2055,7 @@ remove_selected_bookmarks (GtkPlacesSidebar *sidebar)
                return;
        }
 
-       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                            PLACES_SIDEBAR_COLUMN_INDEX, &index,
                            -1);
 
@@ -2096,13 +2081,13 @@ mount_shortcut_cb (GtkMenuItem           *item,
                return;
        }
 
-       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                            PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
                            -1);
 
        if (volume != NULL) {
 #if DO_NOT_COMPILE
-               nautilus_file_operations_mount_volume (NULL, volume);
+               nautilus_file_operations_mount_volume (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))), volume);
                g_object_unref (volume);
 #endif
        }
@@ -2114,7 +2099,6 @@ unmount_done (gpointer data)
        GtkPlacesSidebar *sidebar;
 
        sidebar = data;
-       emit_initiated_unmount (sidebar, FALSE);
        g_object_unref (sidebar);
 }
 
@@ -2123,7 +2107,6 @@ do_unmount (GMount *mount,
            GtkPlacesSidebar *sidebar)
 {
        if (mount != NULL) {
-               emit_initiated_unmount (sidebar, TRUE);
 #if DO_NOT_COMPILE
                nautilus_file_operations_unmount_mount_full (NULL, mount, FALSE, TRUE,
                                                             unmount_done,
@@ -2142,7 +2125,7 @@ do_unmount_selection (GtkPlacesSidebar *sidebar)
                return;
        }
 
-       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                            PLACES_SIDEBAR_COLUMN_MOUNT, &mount,
                            -1);
 
@@ -2153,10 +2136,38 @@ do_unmount_selection (GtkPlacesSidebar *sidebar)
 }
 
 static void
-unmount_shortcut_cb (GtkMenuItem           *item,
-                    GtkPlacesSidebar *sidebar)
+unmount_shortcut_cb (GtkMenuItem           *item,
+                    GtkPlacesSidebar *sidebar)
+{
+       do_unmount_selection (sidebar);
+}
+
+static void
+show_unmount_progress_cb (GMountOperation *op,
+                         const gchar *message,
+                         gint64 time_left,
+                         gint64 bytes_left,
+                         gpointer user_data)
+{
+#if DO_NOT_COMPILE
+       NautilusApplication *app = NAUTILUS_APPLICATION (g_application_get_default ());
+
+       if (bytes_left == 0) {
+               nautilus_application_notify_unmount_done (app, message);
+       } else {
+               nautilus_application_notify_unmount_show (app, message);
+       }
+#endif
+}
+
+static void
+show_unmount_progress_aborted_cb (GMountOperation *op,
+                                 gpointer user_data)
 {
-       do_unmount_selection (sidebar);
+#if DO_NOT_COMPILE
+       NautilusApplication *app = NAUTILUS_APPLICATION (g_application_get_default ());
+       nautilus_application_notify_unmount_done (app, NULL);
+#endif
 }
 
 static void
@@ -2170,7 +2181,6 @@ drive_eject_cb (GObject *source_object,
        char *name;
 
        sidebar = user_data;
-       emit_initiated_unmount (sidebar, FALSE);
 
        error = NULL;
        if (!g_drive_eject_with_operation_finish (G_DRIVE (source_object), res, &error)) {
@@ -2198,7 +2208,6 @@ volume_eject_cb (GObject *source_object,
        char *name;
 
        sidebar = user_data;
-       emit_initiated_unmount (sidebar, FALSE);
 
        error = NULL;
        if (!g_volume_eject_with_operation_finish (G_VOLUME (source_object), res, &error)) {
@@ -2226,7 +2235,6 @@ mount_eject_cb (GObject *source_object,
        char *name;
 
        sidebar = user_data;
-       emit_initiated_unmount (sidebar, FALSE);
 
        error = NULL;
        if (!g_mount_eject_with_operation_finish (G_MOUNT (source_object), res, &error)) {
@@ -2253,18 +2261,20 @@ do_eject (GMount *mount,
 
        mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
        if (mount != NULL) {
-               emit_initiated_unmount (sidebar, TRUE);
                g_mount_eject_with_operation (mount, 0, mount_op, NULL, mount_eject_cb,
                                              g_object_ref (sidebar));
        } else if (volume != NULL) {
-               emit_initiated_unmount (sidebar, TRUE);
                g_volume_eject_with_operation (volume, 0, mount_op, NULL, volume_eject_cb,
                                              g_object_ref (sidebar));
        } else if (drive != NULL) {
-               emit_initiated_unmount (sidebar, TRUE);
                g_drive_eject_with_operation (drive, 0, mount_op, NULL, drive_eject_cb,
                                              g_object_ref (sidebar));
        }
+
+       g_signal_connect (mount_op, "show-unmount-progress",
+                         G_CALLBACK (show_unmount_progress_cb), sidebar);
+       g_signal_connect (mount_op, "aborted",
+                         G_CALLBACK (show_unmount_progress_aborted_cb), sidebar);
        g_object_unref (mount_op);
 }
 
@@ -2281,7 +2291,7 @@ eject_shortcut_cb (GtkMenuItem           *item,
                return;
        }
 
-       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                            PLACES_SIDEBAR_COLUMN_MOUNT, &mount,
                            PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
                            PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
@@ -2302,7 +2312,7 @@ eject_or_unmount_bookmark (GtkPlacesSidebar *sidebar,
        GDrive *drive;
        gboolean ret;
 
-       model = GTK_TREE_MODEL (sidebar->filter_model);
+       model = GTK_TREE_MODEL (sidebar->store);
 
        if (!path) {
                return FALSE;
@@ -2350,7 +2360,7 @@ eject_or_unmount_selection (GtkPlacesSidebar *sidebar)
                return FALSE;
        }
 
-       path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->filter_model), &iter);
+       path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &iter);
        if (path == NULL) {
                return FALSE;
        }
@@ -2400,7 +2410,7 @@ rescan_shortcut_cb (GtkMenuItem           *item,
                return;
        }
 
-       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                            PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
                            -1);
 
@@ -2448,7 +2458,7 @@ start_shortcut_cb (GtkMenuItem           *item,
                return;
        }
 
-       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                            PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
                            -1);
 
@@ -2475,7 +2485,6 @@ drive_stop_cb (GObject *source_object,
        char *name;
 
        sidebar = user_data;
-       emit_initiated_unmount (sidebar, FALSE);
 
        error = NULL;
        if (!g_drive_poll_for_media_finish (G_DRIVE (source_object), res, &error)) {
@@ -2503,7 +2512,7 @@ stop_shortcut_cb (GtkMenuItem           *item,
                return;
        }
 
-       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                            PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
                            -1);
 
@@ -2511,7 +2520,6 @@ stop_shortcut_cb (GtkMenuItem           *item,
                GMountOperation *mount_op;
 
                mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
-               emit_initiated_unmount (sidebar, TRUE);
                g_drive_stop (drive, G_MOUNT_UNMOUNT_NONE, mount_op, NULL, drive_stop_cb,
                              g_object_ref (sidebar));
                g_object_unref (mount_op);
@@ -2533,17 +2541,9 @@ find_prev_or_next_row (GtkPlacesSidebar *sidebar,
                       GtkTreeIter *iter,
                       gboolean go_up)
 {
-       GtkTreeSelection *selection;
-       GtkTreeModel *model;
-       int place_type;
+       GtkTreeModel *model = GTK_TREE_MODEL (sidebar->store);
        gboolean res;
-
-       selection = gtk_tree_view_get_selection (sidebar->tree_view);
-       res = gtk_tree_selection_get_selected (selection, &model, iter);
-
-       if (!res) {
-               goto out;
-       }
+       int place_type;
 
        if (go_up) {
                res = gtk_tree_model_iter_previous (model, iter);
@@ -2564,7 +2564,6 @@ find_prev_or_next_row (GtkPlacesSidebar *sidebar,
                }
        }
 
- out:
        return res;
 }
 
@@ -2580,77 +2579,139 @@ find_next_row (GtkPlacesSidebar *sidebar, GtkTreeIter *iter)
        return find_prev_or_next_row (sidebar, iter, FALSE);
 }
 
+static void
+properties_cb (GtkMenuItem      *item,
+              GtkPlacesSidebar *sidebar)
+{
+#if DO_NOT_COMPILE
+       GtkTreeModel *model;
+       GtkTreePath *path = NULL;
+       GtkTreeIter iter;
+       GList *list;
+       NautilusFile *file;
+       char *uri;
+
+       model = gtk_tree_view_get_model (sidebar->tree_view);
+       gtk_tree_view_get_cursor (sidebar->tree_view, &path, NULL);
+
+       if (path == NULL || !gtk_tree_model_get_iter (model, &iter, path)) {
+               gtk_tree_path_free (path);
+               return;
+       }
+
+       gtk_tree_model_get (model, &iter, PLACES_SIDEBAR_COLUMN_URI, &uri, -1);
+
+       if (uri != NULL) {
+
+               file = nautilus_file_get_by_uri (uri);
+               list = g_list_prepend (NULL, nautilus_file_ref (file));
+
+               nautilus_properties_window_present (list, GTK_WIDGET (sidebar), NULL);
+
+               nautilus_file_list_free (list);
+               g_free (uri);
+       }
+
+       gtk_tree_path_free (path);
+#endif
+}
+
+static gboolean
+gtk_places_sidebar_focus (GtkWidget *widget,
+                         GtkDirectionType direction)
+{
+       GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (widget);
+       GtkTreePath *path;
+       GtkTreeIter iter;
+       gboolean res;
+
+       res = get_selected_iter (sidebar, &iter);
+
+       if (!res) {
+               gtk_tree_model_get_iter_first (GTK_TREE_MODEL (sidebar->store), &iter);
+               res = find_next_row (sidebar, &iter);
+               if (res) {
+                       path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &iter);
+                       gtk_tree_view_set_cursor (sidebar->tree_view, path, NULL, FALSE);
+                       gtk_tree_path_free (path);
+               }
+       }
+
+       return GTK_WIDGET_CLASS (gtk_places_sidebar_parent_class)->focus (widget, direction);
+}
+
 /* Handler for GtkWidget::key-press-event on the shortcuts list */
 static gboolean
 bookmarks_key_press_event_cb (GtkWidget             *widget,
                              GdkEventKey           *event,
                              GtkPlacesSidebar *sidebar)
 {
-  guint modifiers;
-  GtkTreeIter iter;
-
-  modifiers = gtk_accelerator_get_default_mod_mask ();
-
-  if ((event->keyval == GDK_KEY_Return ||
-       event->keyval == GDK_KEY_KP_Enter ||
-       event->keyval == GDK_KEY_ISO_Enter ||
-       event->keyval == GDK_KEY_space)) {
-
-      GtkTreeModel *model;
-      GtkTreeSelection *selection;
-      GtkTreeIter iter;
-      GtkPlacesOpenMode open_mode = GTK_PLACES_OPEN_MODE_NORMAL;
-
-      if ((event->state & modifiers) == GDK_SHIFT_MASK) {
-       open_mode = GTK_PLACES_OPEN_MODE_NEW_TAB;
-      } else if ((event->state & modifiers) == GDK_CONTROL_MASK) {
-       open_mode = GTK_PLACES_OPEN_MODE_NEW_WINDOW;
-      }
-
-      model = gtk_tree_view_get_model (sidebar->tree_view);
-      selection = gtk_tree_view_get_selection (sidebar->tree_view);
-      gtk_tree_selection_get_selected (selection, NULL, &iter);
-
-      open_selected_bookmark (sidebar, model, &iter, open_mode);
-
-      return TRUE;
-  }
-
-  if (event->keyval == GDK_KEY_Down &&
-      (event->state & modifiers) == GDK_MOD1_MASK) {
-      return eject_or_unmount_selection (sidebar);
-  }
-
-  if (event->keyval == GDK_KEY_Up) {
-      if (find_prev_row (sidebar, &iter)) {
-             gtk_tree_selection_select_iter (gtk_tree_view_get_selection (sidebar->tree_view),
-                                             &iter);
-      }
-      return TRUE;
-  }
-
-  if (event->keyval == GDK_KEY_Down) {
-      if (find_next_row (sidebar, &iter)) {
-             gtk_tree_selection_select_iter (gtk_tree_view_get_selection (sidebar->tree_view),
-                                             &iter);
-      }
-      return TRUE;
-  }
-
-  if ((event->keyval == GDK_KEY_Delete
-      || event->keyval == GDK_KEY_KP_Delete)
-      && (event->state & modifiers) == 0) {
-      remove_selected_bookmarks (sidebar);
-      return TRUE;
-  }
-
-  if ((event->keyval == GDK_KEY_F2)
-      && (event->state & modifiers) == 0) {
-      rename_selected_bookmark (sidebar);
-      return TRUE;
-  }
-
-  return FALSE;
+       guint modifiers;
+       GtkTreeIter selected_iter;
+       GtkTreePath *path;
+
+       if (!get_selected_iter (sidebar, &selected_iter)) {
+               return FALSE;
+       }
+
+       modifiers = gtk_accelerator_get_default_mod_mask ();
+
+       if ((event->keyval == GDK_KEY_Return ||
+               event->keyval == GDK_KEY_KP_Enter ||
+               event->keyval == GDK_KEY_ISO_Enter ||
+               event->keyval == GDK_KEY_space)) {
+
+               GtkPlacesOpenMode open_mode = GTK_PLACES_OPEN_MODE_NORMAL;
+
+               if ((event->state & modifiers) == GDK_SHIFT_MASK) {
+                       open_mode = GTK_PLACES_OPEN_MODE_NEW_TAB;
+               } else if ((event->state & modifiers) == GDK_CONTROL_MASK) {
+                       open_mode = GTK_PLACES_OPEN_MODE_NEW_WINDOW;
+               }
+
+               open_selected_bookmark (sidebar, GTK_TREE_MODEL (sidebar->store),
+                                       &selected_iter, open_mode);
+
+               return TRUE;
+       }
+
+       if (event->keyval == GDK_KEY_Down &&
+           (event->state & modifiers) == GDK_MOD1_MASK) {
+               return eject_or_unmount_selection (sidebar);
+       }
+
+       if (event->keyval == GDK_KEY_Up) {
+               if (find_prev_row (sidebar, &selected_iter)) {
+                       path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &selected_iter);
+                       gtk_tree_view_set_cursor (sidebar->tree_view, path, NULL, FALSE);
+                       gtk_tree_path_free (path);
+               }
+               return TRUE;
+       }
+
+       if (event->keyval == GDK_KEY_Down) {
+               if (find_next_row (sidebar, &selected_iter)) {
+                       path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &selected_iter);
+                       gtk_tree_view_set_cursor (sidebar->tree_view, path, NULL, FALSE);
+                       gtk_tree_path_free (path);
+               }
+               return TRUE;
+       }
+
+       if ((event->keyval == GDK_KEY_Delete
+            || event->keyval == GDK_KEY_KP_Delete)
+           && (event->state & modifiers) == 0) {
+               remove_selected_bookmarks (sidebar);
+               return TRUE;
+       }
+
+       if ((event->keyval == GDK_KEY_F2)
+           && (event->state & modifiers) == 0) {
+               rename_selected_bookmark (sidebar);
+               return TRUE;
+       }
+
+       return FALSE;
 }
 
 static GtkMenuItem *
@@ -2786,6 +2847,19 @@ bookmarks_build_popup_menu (GtkPlacesSidebar *sidebar)
                    G_CALLBACK (empty_trash_cb), sidebar);
        gtk_widget_show (item);
        gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
+
+       /* Properties menu item */
+
+       sidebar->popup_menu_properties_separator_item =
+               GTK_WIDGET (eel_gtk_menu_append_separator (GTK_MENU (sidebar->popup_menu)));
+
+       item = gtk_menu_item_new_with_mnemonic (_("_Properties"));
+       sidebar->popup_menu_properties_item = item;
+       g_signal_connect (item, "activate",
+                         G_CALLBACK (properties_cb), sidebar);
+       gtk_widget_show (item);
+       gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
+
 #endif
 
        bookmarks_check_popup_sensitivity (sidebar);
@@ -2818,7 +2892,7 @@ bookmarks_popup_menu (GtkPlacesSidebar *sidebar,
        } else {
                button = 0;
        }
-       
+
        gtk_menu_popup (GTK_MENU (sidebar->popup_menu),         /* menu */
                        NULL,                                   /* parent_menu_shell */
                        NULL,                                   /* parent_menu_item */
@@ -2848,6 +2922,7 @@ bookmarks_button_release_event_cb (GtkWidget *widget,
        GtkTreeIter iter;
        GtkTreeModel *model;
        GtkTreeView *tree_view;
+       gboolean ret = FALSE;
        gboolean res;
 
        path = NULL;
@@ -2866,177 +2941,50 @@ bookmarks_button_release_event_cb (GtkWidget *widget,
        tree_view = GTK_TREE_VIEW (widget);
        model = gtk_tree_view_get_model (tree_view);
 
-       if (event->button == 1) {
-
-               if (event->window != gtk_tree_view_get_bin_window (tree_view)) {
-                       return FALSE;
-               }
-
-               res = gtk_tree_view_get_path_at_pos (tree_view, (int) event->x, (int) event->y,
-                                                    &path, NULL, NULL, NULL);
-
-               if (!res) {
-                       return FALSE;
-               }
-
-               gtk_tree_model_get_iter (model, &iter, path);
-
-               open_selected_bookmark (sidebar, model, &iter, 0);
-
-               gtk_tree_path_free (path);
-       }
-
-       return FALSE;
-}
-
-static void
-update_eject_buttons (GtkPlacesSidebar *sidebar,
-                     GtkTreePath           *path)
-{
-       GtkTreeIter iter;
-       gboolean icon_visible, path_same;
-
-       icon_visible = TRUE;
-
-       if (path == NULL && sidebar->eject_highlight_path == NULL) {
-               /* Both are null - highlight up to date */
-               return;
-       }
-
-       path_same = (path != NULL) &&
-               (sidebar->eject_highlight_path != NULL) &&
-               (gtk_tree_path_compare (sidebar->eject_highlight_path, path) == 0);
-
-       if (path_same) {
-               /* Same path - highlight up to date */
-               return;
-       }
-
-       if (path) {
-               gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->filter_model),
-                                        &iter,
-                                        path);
-
-               gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model),
-                                   &iter,
-                                   PLACES_SIDEBAR_COLUMN_EJECT, &icon_visible,
-                                   -1);
-       }
-
-       if (!icon_visible || path == NULL || !path_same) {
-               /* remove highlighting and reset the saved path, as we are leaving
-                * an eject button area.
-                */
-               if (sidebar->eject_highlight_path) {
-                       gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->store),
-                                                &iter,
-                                                sidebar->eject_highlight_path);
-
-                       gtk_list_store_set (sidebar->store,
-                                           &iter,
-                                           PLACES_SIDEBAR_COLUMN_EJECT_ICON, get_eject_icon (sidebar, FALSE),
-                                           -1);
-                       gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (sidebar->filter_model));
-
-                       gtk_tree_path_free (sidebar->eject_highlight_path);
-                       sidebar->eject_highlight_path = NULL;
-               }
-
-               if (!icon_visible) {
-                       return;
-               }
-       }
+       if (event->window != gtk_tree_view_get_bin_window (tree_view)) {
+               return FALSE;
+       }
 
-       if (path != NULL) {
-               /* add highlighting to the selected path, as the icon is visible and
-                * we're hovering it.
-                */
-               gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->store),
-                                        &iter,
-                                        path);
-               gtk_list_store_set (sidebar->store,
-                                   &iter,
-                                   PLACES_SIDEBAR_COLUMN_EJECT_ICON, get_eject_icon (sidebar, TRUE),
-                                   -1);
-               gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (sidebar->filter_model));
+       res = gtk_tree_view_get_path_at_pos (tree_view, (int) event->x, (int) event->y,
+                                            &path, NULL, NULL, NULL);
 
-               sidebar->eject_highlight_path = gtk_tree_path_copy (path);
+       if (!res || path == NULL) {
+               return FALSE;
        }
-}
-
-static gboolean
-bookmarks_motion_event_cb (GtkWidget             *widget,
-                          GdkEventMotion        *event,
-                          GtkPlacesSidebar *sidebar)
-{
-       GtkTreePath *path;
-
-       path = NULL;
 
-       if (over_eject_button (sidebar, event->x, event->y, &path)) {
-               update_eject_buttons (sidebar, path);
+       res = gtk_tree_model_get_iter (model, &iter, path);
+       if (!res) {
                gtk_tree_path_free (path);
-
-               return TRUE;
-       }
-
-       update_eject_buttons (sidebar, NULL);
-
-       return FALSE;
-}
-
-/* Callback used when a button is pressed on the shortcuts list.
- * We trap button 3 to bring up a popup menu, and button 2 to
- * open in a new tab.
- */
-static gboolean
-bookmarks_button_press_event_cb (GtkWidget             *widget,
-                                GdkEventButton        *event,
-                                GtkPlacesSidebar *sidebar)
-{
-       if (event->type != GDK_BUTTON_PRESS) {
-               /* ignore multiple clicks */
-               return TRUE;
+               return FALSE;
        }
 
-       if (event->button == 3) {
-               bookmarks_popup_menu (sidebar, event);
+       if (event->button == 1) {
+               open_selected_bookmark (sidebar, model, &iter, 0);
        } else if (event->button == 2) {
-               GtkTreeModel *model;
-               GtkTreePath *path;
-               GtkTreeIter iter;
-               GtkTreeView *tree_view;
                GtkPlacesOpenMode open_mode = GTK_PLACES_OPEN_MODE_NORMAL;
 
-               tree_view = GTK_TREE_VIEW (widget);
-               g_assert (tree_view == sidebar->tree_view);
-
-               model = gtk_tree_view_get_model (tree_view);
-
-               gtk_tree_view_get_path_at_pos (tree_view, (int) event->x, (int) event->y,
-                                              &path, NULL, NULL, NULL);
-               gtk_tree_model_get_iter (model, &iter, path);
-
-               if (sidebar->multiple_tabs_supported) {
-                       if (event->state & GDK_CONTROL_MASK)
-                               open_mode = GTK_PLACES_OPEN_MODE_NEW_WINDOW;
-                       else
-                               open_mode = GTK_PLACES_OPEN_MODE_NEW_TAB;
-               } else {
-                       open_mode = GTK_PLACES_OPEN_MODE_NEW_WINDOW;
-               }
+               open_mode = ((event->state & GDK_CONTROL_MASK) ?
+                            GTK_PLACES_OPEN_MODE_NEW_WINDOW :
+                            GTK_PLACES_OPEN_MODE_NEW_TAB);
 
                open_selected_bookmark (sidebar, model, &iter, open_mode);
+               ret = TRUE;
+       } else if (event->button == 3) {
+               PlaceType row_type;
 
-               if (path != NULL) {
-                       gtk_tree_path_free (path);
-                       return TRUE;
+               gtk_tree_model_get (model, &iter,
+                                   PLACES_SIDEBAR_COLUMN_ROW_TYPE, &row_type,
+                                   -1);
+
+               if (row_type != PLACES_HEADING) {
+                       bookmarks_popup_menu (sidebar, event);
                }
        }
 
-       return FALSE;
-}
+       gtk_tree_path_free (path);
 
+       return ret;
+}
 
 static void
 bookmarks_edited (GtkCellRenderer       *cell,
@@ -3053,8 +3001,8 @@ bookmarks_edited (GtkCellRenderer       *cell,
        g_object_set (cell, "editable", FALSE, NULL);
 
        path = gtk_tree_path_new_from_string (path_string);
-       gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->filter_model), &iter, path);
-       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->filter_model), &iter,
+       gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->store), &iter, path);
+       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                            PLACES_SIDEBAR_COLUMN_INDEX, &index,
                            -1);
        gtk_tree_path_free (path);
@@ -3188,6 +3136,99 @@ heading_cell_renderer_func (GtkTreeViewColumn *column,
        }
 }
 
+static gint
+places_sidebar_sort_func (GtkTreeModel *model,
+                         GtkTreeIter *iter_a,
+                         GtkTreeIter *iter_b,
+                         gpointer user_data)
+{
+       SectionType section_type_a, section_type_b;
+       PlaceType place_type_a, place_type_b;
+       gint retval = 0;
+
+       gtk_tree_model_get (model, iter_a,
+                           PLACES_SIDEBAR_COLUMN_SECTION_TYPE, &section_type_a,
+                           PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type_a,
+                           -1);
+       gtk_tree_model_get (model, iter_b,
+                           PLACES_SIDEBAR_COLUMN_SECTION_TYPE, &section_type_b,
+                           PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type_b,
+                           -1);
+
+       /* fall back to the default order if we're not in the
+        * XDG part of the computer section.
+        */
+       if ((section_type_a == section_type_b) &&
+           (section_type_a == SECTION_COMPUTER) &&
+           (place_type_a == place_type_b) &&
+           (place_type_a == PLACES_XDG_DIR)) {
+               gchar *name_a, *name_b;
+
+               gtk_tree_model_get (model, iter_a,
+                                   PLACES_SIDEBAR_COLUMN_NAME, &name_a,
+                                   -1);
+               gtk_tree_model_get (model, iter_b,
+                                   PLACES_SIDEBAR_COLUMN_NAME, &name_b,
+                                   -1);
+
+               retval = g_utf8_collate (name_a, name_b);
+
+               g_free (name_a);
+               g_free (name_b);
+       }
+
+       return retval;
+}
+
+static void
+update_hostname (GtkPlacesSidebar *sidebar)
+{
+       GVariant *variant;
+       gsize len;
+       const gchar *hostname;
+
+       if (sidebar->hostnamed_proxy == NULL)
+               return;
+
+       variant = g_dbus_proxy_get_cached_property (sidebar->hostnamed_proxy,
+                                                   "PrettyHostname");
+       if (variant == NULL) {
+               return;
+       }
+
+       hostname = g_variant_get_string (variant, &len);
+       if (len > 0 &&
+           g_strcmp0 (sidebar->hostname, hostname) != 0) {
+               g_free (sidebar->hostname);
+               sidebar->hostname = g_strdup (hostname);
+               update_places (sidebar);
+       }
+
+       g_variant_unref (variant);
+}
+
+static void
+hostname_proxy_new_cb (GObject      *source_object,
+                      GAsyncResult *res,
+                      gpointer      user_data)
+{
+       GtkPlacesSidebar *sidebar = user_data;
+       GError *error = NULL;
+
+       sidebar->hostnamed_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+       if (error != NULL) {
+               g_debug ("Failed to create D-Bus proxy: %s", error->message);
+               g_error_free (error);
+               return;
+       }
+
+       g_signal_connect_swapped (sidebar->hostnamed_proxy,
+                                 "g-properties-changed",
+                                 G_CALLBACK (update_hostname),
+                                 sidebar);
+       update_hostname (sidebar);
+}
+
 static void
 create_volume_monitor (GtkPlacesSidebar *sidebar)
 {
@@ -3314,9 +3355,10 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
 
        /* icon renderer */
        cell = gtk_cell_renderer_pixbuf_new ();
+       g_object_set (cell, "follow-state", TRUE, NULL);
        gtk_tree_view_column_pack_start (col, cell, FALSE);
        gtk_tree_view_column_set_attributes (col, cell,
-                                            "pixbuf", PLACES_SIDEBAR_COLUMN_ICON,
+                                            "gicon", PLACES_SIDEBAR_COLUMN_GICON,
                                             NULL);
        gtk_tree_view_column_set_cell_data_func (col, cell,
                                                 icon_cell_renderer_func,
@@ -3344,11 +3386,12 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
                      /* align right, because for some reason gtk+ expands
                         this even though we tell it not to. */
                      "xalign", 1.0,
+                     "follow-state", TRUE,
                      NULL);
        gtk_tree_view_column_pack_start (col, cell, FALSE);
        gtk_tree_view_column_set_attributes (col, cell,
                                             "visible", PLACES_SIDEBAR_COLUMN_EJECT,
-                                            "pixbuf", PLACES_SIDEBAR_COLUMN_EJECT_ICON,
+                                            "gicon", PLACES_SIDEBAR_COLUMN_EJECT_GICON,
                                             NULL);
 
        /* normal text renderer */
@@ -3374,32 +3417,21 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
        gtk_tree_view_column_set_max_width (GTK_TREE_VIEW_COLUMN (col), 24);
        gtk_tree_view_append_column (tree_view, col);
 
-       sidebar->store = gtk_list_store_new (PLACES_SIDEBAR_COLUMN_COUNT,
-                                            G_TYPE_INT,
-                                            G_TYPE_STRING,
-                                            G_TYPE_DRIVE,
-                                            G_TYPE_VOLUME,
-                                            G_TYPE_MOUNT,
-                                            G_TYPE_STRING,
-                                            GDK_TYPE_PIXBUF,
-                                            G_TYPE_INT,
-                                            G_TYPE_BOOLEAN,
-                                            G_TYPE_BOOLEAN,
-                                            G_TYPE_BOOLEAN,
-                                            G_TYPE_STRING,
-                                            GDK_TYPE_PIXBUF,
-                                            G_TYPE_INT,
-                                            G_TYPE_STRING);
-
+       sidebar->store = shortcuts_model_new (sidebar);
        gtk_tree_view_set_tooltip_column (tree_view, PLACES_SIDEBAR_COLUMN_TOOLTIP);
 
-       sidebar->filter_model = shortcuts_model_filter_new (sidebar,
-                                                           GTK_TREE_MODEL (sidebar->store),
-                                                           NULL);
+       gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sidebar->store),
+                                             PLACES_SIDEBAR_COLUMN_NAME,
+                                             GTK_SORT_ASCENDING);
+       gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sidebar->store),
+                                        PLACES_SIDEBAR_COLUMN_NAME,
+                                        places_sidebar_sort_func,
+                                        sidebar, NULL);
 
-       gtk_tree_view_set_model (tree_view, sidebar->filter_model);
+       gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (sidebar->store));
        gtk_container_add (GTK_CONTAINER (sidebar), GTK_WIDGET (tree_view));
        gtk_widget_show (GTK_WIDGET (tree_view));
+       gtk_tree_view_set_enable_search (tree_view, FALSE);
 
        gtk_widget_show (GTK_WIDGET (sidebar));
        sidebar->tree_view = tree_view;
@@ -3438,10 +3470,6 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
                          G_CALLBACK (bookmarks_selection_changed_cb), sidebar);
        g_signal_connect (tree_view, "popup-menu",
                          G_CALLBACK (bookmarks_popup_menu_cb), sidebar);
-       g_signal_connect (tree_view, "button-press-event",
-                         G_CALLBACK (bookmarks_button_press_event_cb), sidebar);
-       g_signal_connect (tree_view, "motion-notify-event",
-                         G_CALLBACK (bookmarks_motion_event_cb), sidebar);
        g_signal_connect (tree_view, "button-release-event",
                          G_CALLBACK (bookmarks_button_release_event_cb), sidebar);
 
@@ -3453,6 +3481,17 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
                                 G_CALLBACK (trash_state_changed_cb),
                                 sidebar, 0);
 #endif
+
+       sidebar->hostname = g_strdup (_("Computer"));
+       g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+                                 G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
+                                 NULL,
+                                 "org.freedesktop.hostname1",
+                                 "/org/freedesktop/hostname1",
+                                 "org.freedesktop.hostname1",
+                                 NULL,
+                                 hostname_proxy_new_cb,
+                                 sidebar);
 }
 
 static void
@@ -3469,19 +3508,39 @@ gtk_places_sidebar_dispose (GObject *object)
 
        free_drag_data (sidebar);
 
-       if (sidebar->eject_highlight_path != NULL) {
-               gtk_tree_path_free (sidebar->eject_highlight_path);
-               sidebar->eject_highlight_path = NULL;
-       }
-
        if (sidebar->bookmarks_manager != NULL) {
                _gtk_bookmarks_manager_free (sidebar->bookmarks_manager);
                sidebar->bookmarks_manager = NULL;
        }
 
        g_clear_object (&sidebar->store);
-       g_clear_object (&sidebar->volume_monitor);
-       g_clear_object (&sidebar->filter_model);
+
+       if (sidebar->volume_monitor != NULL) {
+               g_signal_handlers_disconnect_by_func (sidebar->volume_monitor, 
+                                                     volume_added_callback, sidebar);
+               g_signal_handlers_disconnect_by_func (sidebar->volume_monitor, 
+                                                     volume_removed_callback, sidebar);
+               g_signal_handlers_disconnect_by_func (sidebar->volume_monitor, 
+                                                     volume_changed_callback, sidebar);
+               g_signal_handlers_disconnect_by_func (sidebar->volume_monitor, 
+                                                     mount_added_callback, sidebar);
+               g_signal_handlers_disconnect_by_func (sidebar->volume_monitor, 
+                                                     mount_removed_callback, sidebar);
+               g_signal_handlers_disconnect_by_func (sidebar->volume_monitor, 
+                                                     mount_changed_callback, sidebar);
+               g_signal_handlers_disconnect_by_func (sidebar->volume_monitor, 
+                                                     drive_disconnected_callback, sidebar);
+               g_signal_handlers_disconnect_by_func (sidebar->volume_monitor, 
+                                                     drive_connected_callback, sidebar);
+               g_signal_handlers_disconnect_by_func (sidebar->volume_monitor, 
+                                                     drive_changed_callback, sidebar);
+
+               g_clear_object (&sidebar->volume_monitor);
+       }
+
+       g_clear_object (&sidebar->hostnamed_proxy);
+       g_free (sidebar->hostname);
+       sidebar->hostname = NULL;
 
        G_OBJECT_CLASS (gtk_places_sidebar_parent_class)->dispose (object);
 }
@@ -3496,6 +3555,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
        gobject_class->dispose = gtk_places_sidebar_dispose;
 
        GTK_WIDGET_CLASS (class)->style_set = gtk_places_sidebar_style_set;
+       GTK_WIDGET_CLASS (class)->focus = gtk_places_sidebar_focus;
 
        /* FIXME: add docstrings for the signals */
 
@@ -3549,24 +3609,14 @@ gtk_places_sidebar_new (void)
        return GTK_WIDGET (g_object_new (gtk_places_sidebar_get_type (), NULL));
 }
 
+\f
 
 /* Drag and drop interfaces */
 
-static void
-shortcuts_model_filter_class_init (ShortcutsModelFilterClass *class)
-{
-}
-
-static void
-shortcuts_model_filter_init (ShortcutsModelFilter *model)
-{
-       model->sidebar = NULL;
-}
-
-/* GtkTreeDragSource::row_draggable implementation for the shortcuts filter model */
+/* GtkTreeDragSource::row_draggable implementation for the shortcuts model */
 static gboolean
-shortcuts_model_filter_row_draggable (GtkTreeDragSource *drag_source,
-                                     GtkTreePath       *path)
+shortcuts_model_row_draggable (GtkTreeDragSource *drag_source,
+                              GtkTreePath       *path)
 {
        GtkTreeModel *model;
        GtkTreeIter iter;
@@ -3589,28 +3639,58 @@ shortcuts_model_filter_row_draggable (GtkTreeDragSource *drag_source,
 
 /* Fill the GtkTreeDragSourceIface vtable */
 static void
-shortcuts_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface)
+shortcuts_model_class_init (ShortcutsModelClass *klass)
 {
-       iface->row_draggable = shortcuts_model_filter_row_draggable;
 }
 
-static GtkTreeModel *
-shortcuts_model_filter_new (GtkPlacesSidebar *sidebar,
-                           GtkTreeModel     *child_model,
-                           GtkTreePath      *root)
+static void
+shortcuts_model_init (ShortcutsModel *model)
 {
-       ShortcutsModelFilter *model;
+       model->sidebar = NULL;
+}
 
-       model = g_object_new (SHORTCUTS_MODEL_FILTER_TYPE,
-                             "child-model", child_model,
-                             "virtual-root", root,
-                             NULL);
+static void
+shortcuts_model_drag_source_iface_init (GtkTreeDragSourceIface *iface)
+{
+       iface->row_draggable = shortcuts_model_row_draggable;
+}
+
+static GtkListStore *
+shortcuts_model_new (GtkPlacesSidebar *sidebar)
+{
+       ShortcutsModel *model;
+       GType model_types[PLACES_SIDEBAR_COLUMN_COUNT] = {
+               G_TYPE_INT, 
+               G_TYPE_STRING,
+               G_TYPE_DRIVE,
+               G_TYPE_VOLUME,
+               G_TYPE_MOUNT,
+               G_TYPE_STRING,
+               G_TYPE_ICON,
+               G_TYPE_INT,
+               G_TYPE_BOOLEAN,
+               G_TYPE_BOOLEAN,
+               G_TYPE_BOOLEAN,
+               G_TYPE_STRING,
+               G_TYPE_ICON,
+               G_TYPE_INT,
+               G_TYPE_STRING
+       };
 
+       model = g_object_new (shortcuts_model_get_type (), NULL);
        model->sidebar = sidebar;
 
-       return GTK_TREE_MODEL (model);
+       gtk_list_store_set_column_types (GTK_LIST_STORE (model),
+                                        PLACES_SIDEBAR_COLUMN_COUNT,
+                                        model_types);
+
+       return GTK_LIST_STORE (model);
 }
 
+\f
+
+/* Public methods for GtkPlacesSidebar */
+
 /**
  * gtk_places_sidebar_set_current_uri:
  * @sidebar: a places sidebar
@@ -3646,10 +3726,10 @@ gtk_places_sidebar_set_current_uri (GtkPlacesSidebar *sidebar, const char *uri)
 
                /* set selection if any place matches the uri */
                gtk_tree_selection_unselect_all (selection);
-               valid = gtk_tree_model_get_iter_first (sidebar->filter_model, &iter);
+               valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (sidebar->store), &iter);
 
                while (valid) {
-                       gtk_tree_model_get (sidebar->filter_model, &iter,
+                       gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
                                            PLACES_SIDEBAR_COLUMN_URI, &iter_uri,
                                            -1);
                        if (iter_uri != NULL) {
@@ -3660,7 +3740,7 @@ gtk_places_sidebar_set_current_uri (GtkPlacesSidebar *sidebar, const char *uri)
                                }
                                g_free (iter_uri);
                        }
-                       valid = gtk_tree_model_iter_next (sidebar->filter_model, &iter);
+                       valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (sidebar->store), &iter);
                }
        }
 }